﻿using Admin.NET.Application.Entity;
using Admin.NET.Application.Enums;
using Admin.NET.Application.Service.ModbusTcpService;
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.Http;
using static Admin.NET.Application.Service.ModbusTcpService.ModbusTcpService;

namespace Admin.NET.Application;

/// <summary>
/// 网关信息服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public class DeviceGateWayService : IDynamicApiController, ITransient
{
    private readonly SqlSugarRepository<DeviceGateWay> _deviceGateWayRep;
    private readonly ModbusInfoManager modbusInfoManager;

    public DeviceGateWayService(SqlSugarRepository<DeviceGateWay> deviceGateWayRep, ModbusInfoManager modbusInfoManager)
    {
        _deviceGateWayRep = deviceGateWayRep;
        this.modbusInfoManager = modbusInfoManager;
    }

    /// <summary>
    /// 分页查询网关信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Page")]
    [DisplayName("分页查询网关信息")]
    public async Task<SqlSugarPagedList<DeviceGateWayOutput>> Page(PageDeviceGateWayInput input)
    {
        input.SearchKey = input.SearchKey?.Trim();
        var query = _deviceGateWayRep.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
                u.GateWayName.Contains(input.SearchKey)
                || u.Sn.Contains(input.SearchKey)
            )
            .WhereIF(input.OrgId > 0, u => u.OrgId == input.OrgId)
            .WhereIF(!string.IsNullOrWhiteSpace(input.GateWayName), u => u.GateWayName.Contains(input.GateWayName.Trim()))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Sn), u => u.Sn.Contains(input.Sn.Trim()))
            //处理外键和TreeSelector相关字段的连接
            .LeftJoin<SysOrg>((u, orgid) => u.OrgId == orgid.Id)
            .Select((u, orgid) => new DeviceGateWayOutput
            {
                Id = u.Id,
                DeviceNo = u.DeviceNo,
                OrgId = u.OrgId,
                OrgIdName = orgid.Name,
                GateWayName = u.GateWayName,
                DeviceAddress = u.DeviceAddress,
                DevicePosition = u.DevicePosition,
                DevicePositionType = u.DevicePositionType,
                Sn = u.Sn,
                DeviceEnableStatus = u.DeviceEnableStatus,
                DeviceWeight = u.DeviceWeight,
                DeviceFuncMonitor = u.DeviceFuncMonitor,
                DeviceFuncCloud = u.DeviceFuncCloud,
                Active = u.Active,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserName = u.CreateUserName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserName = u.UpdateUserName,
                IsDelete = u.IsDelete,
            });
        var pageList = await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
        foreach (var item in pageList.Items)
        {
            var connectDeviceInfo = modbusInfoManager.GetModbusConnectInfoByDeviceId(item.Id);
            var deviceInfo = connectDeviceInfo.Item2;
            if (deviceInfo == null)
            {
                item.Active = Active.NotActive;
            }
            var connectInfo = connectDeviceInfo.Item1;
            if (connectInfo != null && connectInfo.ModbusConnectStatus == Service.ModbusTcp.ModbusConnectStatus.Connected)
            {
                item.Active = Active.Activated;
            }
            else
            {
                item.Active = Active.NotActive;
            }
        }
        return pageList;
    }

    /// <summary>
    /// 增加网关信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    [DisplayName("增加网关信息")]
    public async Task<long> Add(AddDeviceGateWayInput input)
    {
        var entity = input.Adapt<DeviceGateWay>();
        await _deviceGateWayRep.InsertAsync(entity);
        return entity.Id;
    }

    /// <summary>
    /// 删除网关信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    [DisplayName("删除网关信息")]
    public async Task Delete(DeleteDeviceGateWayInput input)
    {
        var entity = await _deviceGateWayRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        //判断网关是否与DeviceInfo关联
        var deviceInfo = await _deviceGateWayRep.Context.Queryable<DeviceInfo>().FirstAsync(d => d.DeviceGateWayId == input.Id);
        if (deviceInfo != null)
        {
            throw Oops.Oh(DeviceErrorCodeEnum.GatewayHasBinUsed);
        }

        await _deviceGateWayRep.FakeDeleteAsync(entity);   //假删除
        //await _deviceGateWayRep.DeleteAsync(entity);   //真删除
    }

    /// <summary>
    /// 更新网关信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    [DisplayName("更新网关信息")]
    public async Task Update(UpdateDeviceGateWayInput input)
    {
        var entity = input.Adapt<DeviceGateWay>();
        await _deviceGateWayRep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
    }

    /// <summary>
    /// 获取网关信息
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "Detail")]
    [DisplayName("获取网关信息")]
    public async Task<DeviceGateWay> Detail([FromQuery] QueryByIdDeviceGateWayInput input)
    {
        return await _deviceGateWayRep.GetFirstAsync(u => u.Id == input.Id);
    }

    /// <summary>
    /// 获取网关信息列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    [DisplayName("获取网关信息列表")]
    public async Task<List<DeviceGateWayOutput>> List([FromQuery] PageDeviceGateWayInput input)
    {
        return await _deviceGateWayRep.AsQueryable().Select<DeviceGateWayOutput>().ToListAsync();
    }

    [HttpGet("SysOrgTree")]
    [DisplayName("获取SysOrgTree")]
    public async Task<dynamic> SysOrgTree()
    {
        return await _deviceGateWayRep.Context.Queryable<SysOrg>().ToTreeAsync(u => u.Children, u => u.Pid, 0);
    }
}